package com.doraemon.staging.application.ioc;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * spring 容器.
 *
 * @author yangz
 * @date 2013-5-31 下午4:51:40
 */
public class SpringContext implements ApplicationContextAware {

    private static ApplicationContext context = null;

    public static ApplicationContext getContext() {
        if (context == null) {
            throw new IllegalStateException("当前没有Spring的applicationContext注入,请确定是否有配置Spring,并在Spring中配置了本类的注入!");
        }
        return context;
    }

    @SuppressWarnings("unchecked")
    public static <E> E getBeanByType(Class<? extends E> type) {
        try {
            String[] beanNames = getContext().getBeanNamesForType(type);
            if (beanNames != null && beanNames.length == 1) {
                return (E) getContext().getBean(beanNames[0]);
            }

            if (beanNames == null || beanNames.length == 0) {
                throw new IllegalStateException("未找到指定类型的Bean定义.");
            }

            throw new IllegalStateException("找到多个同类型的Bean定义.");

        } catch (Throwable th) {
            throw new IllegalStateException("根据类型在Spring上下文查找对象出错:" + type);
        }
    }

    @SuppressWarnings("unchecked")
    public static <E> E getBean(String beanName) {
        try {
            return (E) getContext().getBean(beanName);
        } catch (Throwable th) {
            throw new IllegalStateException("在Spring上下文查找对象出错:" + beanName);
        }
    }

    public static <E> E getBean(Class<E> clazz) {
        return getBeanByType(clazz);
    }

    public static boolean containBean(String beanName) {
        return getContext().containsBean(beanName);
    }

    public void setApplicationContext(ApplicationContext context) throws BeansException {

        if (SpringContext.context != null) {
            throw new IllegalStateException("Spring ioc 容器重复注入, 请检查!");
        }
        SpringContext.context = context;
    }

}
